/*
 * Preferences.java
 *
 * Created on February 11, 2007, 11:26 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package Comm.Util;

import Comm.Util.Exceptions.PreferencesException;
import Comm.Util.Logger;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import javax.microedition.rms.InvalidRecordIDException;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;
import javax.microedition.rms.RecordStoreNotOpenException;

/**
 *
 * @author dmgreen
 */
public class Preferences {
    
    private final String RS_NAME = "PREFERENCES";
    private RecordStore myRecordStore = null;
    
    private int UID_RID = 1;
    
    public static Preferences preferencesObj = null;
    
    public static String LOG_MODE_DEBUG  = "LOG_MODE_DEBUG";
    public static String LOG_MODE_NORMAL = "LOG_MODE_NORMAL";
    
    private boolean MY_DEBUG_MODE = false;
    
    /** Creates a new instance of Preferences */
    public Preferences() {
        initialize();
    }

    
    private void writeUserID(int new_uid) throws Exception {
         doWriteRecord(1, String.valueOf(new_uid));
         Logger.getLog().addLogMessage("Successfully set user id to " + new_uid, Logger.MSG_DEBUG);
    }
    
    private void writeDebugMode(boolean new_debug_mode) throws Exception {
        String debug_value = "";
        if (new_debug_mode == true) {
            debug_value = "true";
        } else {
            debug_value = "false";
        }
       
        doWriteRecord(2,debug_value);
        Logger.getLog().addLogMessage("Successfully set debug mode to " + debug_value, Logger.MSG_DEBUG);
        MY_DEBUG_MODE = new_debug_mode;
    }
    
    
    private void initialize() {
        Logger.getLog().addLogMessage("Initializing preferences", Logger.MSG_DEBUG);
        
        try {
            myRecordStore = RecordStore.openRecordStore(RS_NAME, true);
        }
        catch (RecordStoreException rsnfe) {
             Logger.getLog().addLogMessage("Error opening record store \"" + RS_NAME + "\"", Logger.MSG_ERROR);
             return;
        }
        
        try {
            
            try {
                String record_one = doGetRecord(1);
                Logger.getLog().addLogMessage("Found '" +  record_one + "' for user id", Logger.MSG_DEBUG);
            } catch (InvalidRecordIDException iride) {
                Logger.getLog().addLogMessage("No entry for user id; writing '0'", Logger.MSG_DEBUG);
                writeUserID(0);
            }
            
            try {
                String the_debug_mode = doGetRecord(2);
                Logger.getLog().addLogMessage("Found '" + the_debug_mode + "' for debug mode", Logger.MSG_DEBUG);
                if (the_debug_mode.equals("true")) {
                    MY_DEBUG_MODE = true;
                } else {
                    MY_DEBUG_MODE = false;
                }
            } catch (InvalidRecordIDException iride) {
                Logger.getLog().addLogMessage("No entry for debug mode; writing 'false'", Logger.MSG_DEBUG);
                MY_DEBUG_MODE = false;
                writeDebugMode(false);
            }
            
        } catch (Exception e) {
            Logger.getLog().addLogMessage("Error during initialization!: " + e.getMessage(), Logger.MSG_ERROR);
        }
    }
    
    private void doWriteRecord(int record_num, String data) throws PreferencesException {
       
        ByteArrayOutputStream strmBytes = null;
        DataOutputStream strmData = null; 
        byte[] record = new byte[100];
        
        try {
            // Write data into an internal byte array
           strmBytes = new ByteArrayOutputStream();

           // Write Java data types into the above byte array
           strmData = new DataOutputStream(strmBytes);

           strmData.writeUTF(data);
           // Clear any buffered data
           strmData.flush();

           // Get stream data into byte array and write record
           record = strmBytes.toByteArray();

           myRecordStore.setRecord(record_num,record,0,record.length);
           
       }
       catch (RecordStoreNotOpenException rsnoe) {
            throw new PreferencesException("RSNOE in doWriteRecord (" + rsnoe.getMessage() + ")");
        }
        catch (IOException ioe) {
            throw new PreferencesException("IOE in doWriteRecord (" + ioe.getMessage() + ")");
        }
        catch (InvalidRecordIDException iride) {
            Logger.getLog().addLogMessage("Record " + record_num + " not found (OK): " + iride.getMessage(), Logger.MSG_DEBUG);
            
            try {
                myRecordStore.addRecord(record,0,record.length);
            } 
            catch (RecordStoreNotOpenException rsnoe) {Logger.getLog().addLogMessage("RSNOE error while adding record", Logger.MSG_ERROR);}
            catch (RecordStoreException rse) {Logger.getLog().addLogMessage("RSE error while adding record", Logger.MSG_ERROR);}
        }
        catch (RecordStoreException rse) {
            throw new PreferencesException("RSE in doWriteRecord (" + rse.getMessage() + ")");
        } finally {
            try{
               strmBytes.reset();
               strmBytes.close();
               strmData.close(); 
           } catch (IOException ioe) {}
        }
    }
    
    private String doGetRecord(int record_num) throws PreferencesException, InvalidRecordIDException {
       //Logger.getLog().addLogMessage("in doGetRecord", Logger.MSG_DEBUG);
        
        String my_data= "";
        
        try {
            byte[] recData = new byte[50];
            ByteArrayInputStream strmBytes = new ByteArrayInputStream(recData);
            DataInputStream strmData = new DataInputStream(strmBytes);
            myRecordStore.getRecord(record_num, recData, 0);
            my_data = strmData.readUTF();
            strmBytes.reset();
            strmBytes.close();
            strmData.close();
        }
        catch (RecordStoreNotOpenException rsnoe) {
            throw new PreferencesException("RSNOE in doGetRecord (" + rsnoe.getMessage() + ")");
        }
        catch (InvalidRecordIDException iride) {
            throw new InvalidRecordIDException("IRIDE in doGetRecord (" + iride.getMessage() + ")");
        }
        catch (RecordStoreException rse) {
            throw new PreferencesException("RSE in doGetRecord (" + rse.getMessage() + ")");
        }
        catch (IOException ioe) {
            throw new PreferencesException("IOE in doGetRecord (" + ioe.getMessage() + ")");
        }
        
       return my_data;
    
    }
    
    public boolean getDebugMode() {
        return MY_DEBUG_MODE;
    }
    
    public int getUserID() throws PreferencesException {
        String record_contents = "";
        
        try {
            record_contents = doGetRecord(1);
        } catch (InvalidRecordIDException iride) {
            throw new PreferencesException("Error while fetching user id (" + iride.getMessage() + ")");
        }
            
        try {
            return Integer.parseInt(record_contents);
        } catch (NumberFormatException nfe) {
            Logger.getLog().addLogMessage("Error while parsing user id record (" + nfe.getMessage() + "). Using 0", 
                    Logger.MSG_ERROR);
            return 0;
        }
    }
    
    public void setDebugMode(boolean debug_mode) throws PreferencesException {
        try {
            writeDebugMode(debug_mode);
        } catch (Exception e) {
            throw new PreferencesException(e.getMessage());
        }
    }
    
    public void setUserID(int uid) throws PreferencesException {
        try {
            writeUserID(uid);
        } catch (Exception e) {
            throw new PreferencesException(e.getMessage());
        }
    }
    
    public static Preferences getPreferences() {
        return preferencesObj;
    }
    
    public static Preferences createPreferences() {
        if (preferencesObj == null) {
            preferencesObj = new Preferences();
        }
        return preferencesObj;
    }
    
}
